package abel.wlmr.model.unit;

import java.util.ArrayList;
import java.util.List;

import abel.wlmr.model.WlmrBasePart;
import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrDefaultUnit;
import abel.wlmr.model.WlmrException;
import abel.wlmr.model.type.DataIdBody;
import io.netty.buffer.ByteBuf;

/**
 * B.5.3.2.2 Fn和pn定义
 * Fn 和 pn 定义见表 B.13。
 * 表B.13 检测报文 Fn 定义
 * Fn 名称及说明 pn
 * F1 登录 p0
 * F2 退出登录 p0
 * F3 心跳 p0
 * F4～F248 备用
 * 
 * @author Abel
 *
 */
public class Afn02Part extends WlmrBasePart {

    public static final short F_LOGIN = 1;
    public static final short F_LOGOUT = 2;
    public static final short F_HEART = 3;

    /**
     * 
     */
    public Afn02Part() {
        super();
    }

    /**
     * @param guessedLen
     */
    public Afn02Part(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrBasePart#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        for (short dt : getId().getDt().typeList()) {
            if (dt == F_HEART && unitList.size() == 0) {
                throw new IllegalArgumentException("heart should contain 1 unit:");
            }
        }

        return super.appendBuf(buf);
    }

    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (getGuessedLength() < DataIdBody.FIXED_LEN) {
            throw new WlmrException("not enough bytes for data id.");
        }

        id = new DataIdBody();
        id.parseBuf(buf);
        short len = (short) (getGuessedLength() - DataIdBody.FIXED_LEN);

        // for p0.
        List<WlmrBaseUnit> units = new ArrayList<>();
        unitList.add(units);

        switch (id.getDt().firstType()) {
        case F_LOGIN:
        case F_LOGOUT:
            // empty unit.
            break;

        case F_HEART:

        {
            Afn02F3Unit unit = new Afn02F3Unit(len);
            int plen = unit.parseBuf(buf);
            if (plen < 0) {
                throw new WlmrException("not enough bytes for 02-F3");
            }

            len -= plen;
            units.add(unit);

            break;
        }

        default:

        {
            WlmrBaseUnit unit = new WlmrDefaultUnit(len);
            len -= unit.parseBuf(buf);
            units.add(unit);
        }
        }

        return getGuessedLength();
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getMinLength()
     */
    @Override
    public int getMinLength() {
        return DataIdBody.FIXED_LEN;
    }

}
